import * as Cesium from 'cesium'

/**
 * 相机事件管理器
 * 监听相机高度和位置变化，自动触发瓦片加载
 */
export class CameraEventManager {
  constructor(viewer, loadVectorTilesCallback) {
    this.viewer = viewer
    this.loadVectorTilesCallback = loadVectorTilesCallback
    this.lastCameraHeight = null
    this.lastCameraPosition = null
    this.lastZoomLevel = null // 记录上次的缩放层级
    this.heightChangeThreshold = 1000 // 高度变化阈值（米）
    this.positionChangeThreshold = 5000 // 位置变化阈值（米）
    this.movementRangeLimit = 20000 // 移动范围限制（米），在此范围内不触发刷新
    this.debounceTimer = null
    this.debounceDelay = 500 // 防抖延迟（毫秒）
    this.isEnabled = false

    // 绑定方法到实例
    this.handleCameraMove = this.handleCameraMove.bind(this)
    this.handleCameraMoveEnd = this.handleCameraMoveEnd.bind(this)
  }

  /**
   * 启用相机事件监听
   */
  enable () {
    if (this.isEnabled) return

    this.isEnabled = true
    this.lastCameraHeight = this.getCurrentCameraHeight()
    this.lastCameraPosition = this.getCurrentCameraPosition()
    this.lastZoomLevel = this.getCurrentZoomLevel() // 记录初始缩放层级

    // 监听相机移动事件
    this.viewer.camera.moveStart.addEventListener(this.handleCameraMove)
    this.viewer.camera.moveEnd.addEventListener(this.handleCameraMoveEnd)

    console.log('相机事件监听已启用')
  }

  /**
   * 禁用相机事件监听
   */
  disable () {
    if (!this.isEnabled) return

    this.isEnabled = false

    // 移除事件监听器
    this.viewer.camera.moveStart.removeEventListener(this.handleCameraMove)
    this.viewer.camera.moveEnd.removeEventListener(this.handleCameraMoveEnd)

    // 清除定时器
    if (this.debounceTimer) {
      clearTimeout(this.debounceTimer)
      this.debounceTimer = null
    }

    console.log('相机事件监听已禁用')
  }

  /**
   * 处理相机移动开始事件
   */
  handleCameraMove () {
    // 相机移动开始时不做处理，等待移动结束
  }

  /**
   * 处理相机移动结束事件
   */
  handleCameraMoveEnd () {
    if (!this.isEnabled) return

    // 使用防抖，避免频繁触发
    if (this.debounceTimer) {
      clearTimeout(this.debounceTimer)
    }

    this.debounceTimer = setTimeout(() => {
      this.checkCameraChange()
    }, this.debounceDelay)
  }

  /**
   * 检查相机变化（高度、位置和缩放层级）
   */
  checkCameraChange () {
    const currentHeight = this.getCurrentCameraHeight()
    const currentPosition = this.getCurrentCameraPosition()
    const currentZoomLevel = this.getCurrentZoomLevel()

    let shouldReload = false
    let changeReason = ''

    // 首先检查缩放层级是否发生变化
    if (this.lastZoomLevel !== null && currentZoomLevel !== this.lastZoomLevel) {
      shouldReload = true
      changeReason = `缩放层级变化: ${this.lastZoomLevel} -> ${currentZoomLevel}`
      console.log(changeReason)
    } else {
      // 如果缩放层级没有变化，检查高度和位置变化

      // 检查高度变化
      if (this.lastCameraHeight !== null) {
        const heightDifference = Math.abs(currentHeight - this.lastCameraHeight)
        if (heightDifference >= this.heightChangeThreshold) {
          shouldReload = true
          changeReason = `高度变化: ${this.lastCameraHeight.toFixed(0)}m -> ${currentHeight.toFixed(0)}m (变化: ${heightDifference.toFixed(0)}m)`
          console.log(changeReason)
        }
      }

      // 检查位置变化（仅在缩放层级未变化时检查）
      if (!shouldReload && this.lastCameraPosition !== null && currentPosition !== null) {
        const distance = Cesium.Cartesian3.distance(this.lastCameraPosition, currentPosition)

        // 如果移动距离超过阈值，但仍在限制范围内，不触发刷新
        if (distance >= this.positionChangeThreshold) {
          if (distance > this.movementRangeLimit) {
            shouldReload = true
            changeReason = `位置变化超出范围限制: 移动距离 ${distance.toFixed(0)}m (限制: ${this.movementRangeLimit}m)`
            console.log(changeReason)
          } else {
            console.log(`位置变化在允许范围内: 移动距离 ${distance.toFixed(0)}m (限制: ${this.movementRangeLimit}m)，不触发刷新`)
          }
        }
      }
    }

    // 更新记录的位置和层级
    this.lastCameraHeight = currentHeight
    this.lastCameraPosition = currentPosition
    this.lastZoomLevel = currentZoomLevel

    // 如果检测到显著变化，触发瓦片重新加载
    if (shouldReload) {
      // 调用瓦片加载回调
      if (this.loadVectorTilesCallback && typeof this.loadVectorTilesCallback === 'function') {
        this.loadVectorTilesCallback()
      }
    }
  }

  /**
   * 获取当前缩放层级
   */
  getCurrentZoomLevel () {
    if (!this.viewer || !this.viewer.camera) {
      return 0
    }

    const height = this.getCurrentCameraHeight()

    // 根据相机高度计算缩放层级（与CesiumContainer.vue中的逻辑保持一致）
    if (height > 20000000) return 2      // 极高：全球视角
    if (height > 10000000) return 3      // 很高：大洲视角
    if (height > 5000000) return 4       // 高：洲际视角
    if (height > 2500000) return 5       // 中高：国家视角
    if (height > 1250000) return 6       // 中：大区域视角
    if (height > 600000) return 7        // 中低：省份视角
    if (height > 300000) return 8        // 低：大城市视角
    if (height > 150000) return 9        // 很低：城市视角
    if (height > 75000) return 10        // 极低：城区视角
    if (height > 35000) return 11        // 超低：街道视角
    if (height > 15000) return 12        // 最低：街区视角
    return 13  // 超精细：建筑物视角
  }

  /**
   * 检查相机高度变化（保留原有方法以兼容）
   */
  checkHeightChange () {
    const currentHeight = this.getCurrentCameraHeight()

    if (this.lastCameraHeight === null) {
      this.lastCameraHeight = currentHeight
      return
    }

    const heightDifference = Math.abs(currentHeight - this.lastCameraHeight)

    // 如果高度变化超过阈值，触发瓦片重新加载
    if (heightDifference >= this.heightChangeThreshold) {
      console.log(`相机高度变化: ${this.lastCameraHeight.toFixed(0)}m -> ${currentHeight.toFixed(0)}m (变化: ${heightDifference.toFixed(0)}m)`)

      this.lastCameraHeight = currentHeight

      // 调用瓦片加载回调
      if (this.loadVectorTilesCallback && typeof this.loadVectorTilesCallback === 'function') {
        this.loadVectorTilesCallback()
      }
    }
  }

  /**
   * 获取当前相机高度
   */
  getCurrentCameraHeight () {
    if (!this.viewer || !this.viewer.camera) {
      return 0
    }

    const position = this.viewer.camera.positionCartographic
    return position ? position.height : 0
  }

  /**
   * 获取当前相机位置
   */
  getCurrentCameraPosition () {
    if (!this.viewer || !this.viewer.camera) {
      return null
    }

    return this.viewer.camera.position
  }

  /**
   * 设置高度变化阈值
   * @param {number} threshold - 高度变化阈值（米）
   */
  setHeightChangeThreshold (threshold) {
    this.heightChangeThreshold = Math.max(100, threshold) // 最小100米
    console.log(`高度变化阈值已设置为: ${this.heightChangeThreshold}m`)
  }

  /**
   * 设置位置变化阈值
   * @param {number} threshold - 位置变化阈值（米）
   */
  setPositionChangeThreshold (threshold) {
    this.positionChangeThreshold = Math.max(100, threshold) // 最小100米
    console.log(`位置变化阈值已设置为: ${this.positionChangeThreshold}m`)
  }

  /**
   * 设置移动范围限制
   * @param {number} limit - 移动范围限制（米）
   */
  setMovementRangeLimit (limit) {
    this.movementRangeLimit = Math.max(1000, limit) // 最小1000米
    console.log(`移动范围限制已设置为: ${this.movementRangeLimit}m`)
  }

  /**
   * 设置防抖延迟
   * @param {number} delay - 防抖延迟（毫秒）
   */
  setDebounceDelay (delay) {
    this.debounceDelay = Math.max(100, delay) // 最小100毫秒
    console.log(`防抖延迟已设置为: ${this.debounceDelay}ms`)
  }

  /**
   * 获取当前状态信息
   */
  getStatus () {
    return {
      isEnabled: this.isEnabled,
      currentHeight: this.getCurrentCameraHeight(),
      lastHeight: this.lastCameraHeight,
      currentZoomLevel: this.getCurrentZoomLevel(),
      lastZoomLevel: this.lastZoomLevel,
      heightThreshold: this.heightChangeThreshold,
      positionThreshold: this.positionChangeThreshold,
      movementRangeLimit: this.movementRangeLimit,
      debounceDelay: this.debounceDelay
    }
  }

  /**
   * 手动触发相机变化检查
   */
  forceHeightCheck () {
    this.checkCameraChange()
  }

  /**
   * 销毁事件管理器
   */
  destroy () {
    this.disable()
    this.viewer = null
    this.loadVectorTilesCallback = null
  }
}

/**
 * 创建相机事件管理器的便捷函数
 * @param {Cesium.Viewer} viewer - Cesium viewer实例
 * @param {Function} loadVectorTilesCallback - 瓦片加载回调函数
 * @param {Object} options - 配置选项
 * @returns {CameraEventManager} 相机事件管理器实例
 */
export function createCameraEventManager (viewer, loadVectorTilesCallback, options = {}) {
  const manager = new CameraEventManager(viewer, loadVectorTilesCallback)

  // 应用配置选项
  if (options.heightThreshold) {
    manager.setHeightChangeThreshold(options.heightThreshold)
  }

  if (options.positionThreshold) {
    manager.setPositionChangeThreshold(options.positionThreshold)
  }

  if (options.movementRangeLimit) {
    manager.setMovementRangeLimit(options.movementRangeLimit)
  }

  if (options.debounceDelay) {
    manager.setDebounceDelay(options.debounceDelay)
  }

  // 自动启用
  if (options.autoEnable !== false) {
    manager.enable()
  }

  return manager
}
